Photo Share

Latest update: November 2013

In this tutorial, we'll show you how to use PhotoShare! We'll be making use of command.cgi to do this.
This tutorial builds off of android Tutorial 7: Uploading to FlashAir.

Overview

By using PhotoShare, we will publish only the image and date in specified folder of FlashAir.

Note: We recommend that you use a different SSID for PhotoShare. By default all images on your FlashAir will be available to the public once PhotoShare is disabled; however, if you switch back to the original SSID it will be forced to stop sharing. For information about how to change your cards SSID, see Android Tutorial 6: Changing SSID and Network Password.

First, lets add a PhotoShare button on the operation screen.

This image shows the content list

When the user taps the PhotoShare button, we'll display the PhotoShare screen.

This image shows an updated content list

When the user connect to the FlashAir while photoshare is active, we'll display only images that are being shared.

This image shows the new image in an image view

We will need to create the following files in order to build this application:

  • MainActivity.java
  • activity_main.xml
  • ImageViewActivity.java
  • activity_image_view.xml
  • DateListActivity.java
  • activity_date_list.xml
  • list_view_item.xml
  • MemoEditActivity.java
  • activity_memo_edit.xml
  • grid_view_item.xml
  • FlashAirRequest.java
  • PhotoShareActivity.java
  • activity_photoshare.xml

Important: Please note that your project contains a file called AndroidManifest.xml. This file is used to manage application permissions. By default, applications are not permitted to access the internet. The path to this file should look something like: [Project_Folder]/AndroidManifest.xml
You will need to add the following line of code into your AndroidManifest.xml in order for this application to work:

<uses-permission android:name="android.permission.INTERNET" />

Creating Screen Layout

Editting strings.xml

Copy strings.xml from Android Tutorial 7: Uploading to FlashAir, and add the following lines:
The path to this file should look something like: [Project_Folder]/res/values/strings.xml

<string name="photoshare">PhotoShare</string>
<string name="photoshare_enabled_">PhotoShare Enabled.</string>

Creating the List Layout

First, we'll create activity_main.xml. This file determines the layout of our Android App.
This can be found in your layout folder. The path to this file should look something like: [Project_Folder]/res/layout/activity_main.xml

This file will be identical to the activity_main.xml file from Android Tutorial 7: Uploading to FlashAir
Please refer to that tutorial for an explanation of the implementation.

Creating the Image Viewing Layout

Next, create activity_image_view.xml it will determine the layout of our image viewing screen. This can also be found in your layout folder. The path to this file should look something like: [Project_Folder]/res/layout/activity_image_view.xml

This file will be identical to the activity imageview.xml file from Android Tutorial 3: Downloading Content.
Please refer to that tutorial for an explanation of the implementation.

Creating the Date List Layout

Now, create activity_date_list.xml and list_view_item.xml.
activity_date_list.xml determines the layout of our date list.
list_view_item.xml sets the layout of the rows contained in the list.
They can be found in your layout folder.
The path to these files should look something like:
[Project_Folder]/res/layout/activity_date_list.xml
[Project_Folder]/res/layout/list_view_item.xml

These files will be identical to the activity_date_list.xml file and list_view_item.xml file from Android Tutorial 7: Uploading to FlashAir.
Please refer to that tutorial for an explanation of the implementation.

Creating the Operation Screen Layout

Create activity_memo_edit.xml and grid_view_item.xml.
activity_memo_edit.xml determines the layout of our operation screen.
grid_view_item.xml is for displaying the thumbnails.
They can be found in your layout folder.
The path to these files should look something like:
[Project_Folder]/res/layout/activity_memo_edit.xml
[Project_Folder]/res/layout/grid_view_item.xml

grid_view_item.xml will be identical to the grid_view_item.xml from Android Tutorial 7: Uploading to FlashAir.
activity_memo_edit.xml will be almost the same as well, with a button added to it.

You will need to add the following lines into the activity_memo_edit.xml.

activity_memo_edit.xml

<Button
    android:id="@+id/button3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="12dp"
    android:cacheColorHint="#00000000"
    android:text="@string/photoshare"
    android:textColor="@android:color/white"
    android:textSize="20sp" />

Creating the PhotoShare Activity Layout

Next, lets write activity_photoshare.xml, it will determine the layout of our PhotoShare activity screen. It can be found in your layout folder.
The path to this file should look something like: [Project_Folder]/res/layout/activity_photoshare.xml

You want activity_photoshare.xml to look like this:

activity_photoshare.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".PhotoShareActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:text="@string/back"
        android:textColor="@android:color/white"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:scaleType="centerInside"
        android:text="@string/directory_name"
        android:textAlignment="center"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="152dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:gravity="center"
        android:hint="@string/date"
        android:paddingLeft="10dp"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:gravity="center"
        android:paddingLeft="10dp"
        android:text="@string/photoshare_enabled_"
        android:textSize="18sp" />

</LinearLayout>

Creating code

Creating the Content List

The MainActivity class will be identical to the version in Android Tutorial 7: Uploading to FlashAir.
Please refer to that tutorial for an explanation of the implementation.。

Creating the Image Viewing Screen

The ImageViewActivity class will be the same as the version in Android Tutorial 3: Downloading Content.
Please refer to that tutorial for an explanation of the implementation.

Creating the Date List Screen

The DateListActivity class will also be identical to the version in Android Tutorial 7: Uploading FlashAir.
Please refer to that tutorial for an explanation of the implementation.

Creating the Operation Screen

MemoEditActivity.java will be changed however.
We're adding the PhotoShare button behvaior to the version from Android Tutorial 7: Uploading to FlashAir.

Initialization and Enabling PhotoShare

Copy MemoEditActivity.java from Android Tutorial 7: Uploading to FlashAir into your new project.

We will be using command.cgi's op 200 to enable PhotoShare.

  • command.cgi with op=200, folder path, and date.
    • The command should look something like this: http://flashair/command.cgi?op=200&DIR=/DCIM/100__TSB&DATE=17153
    • And it will return the following data:
      • OK If we successfully enabled PhotoShare mode.
      • 400 Bad Request If something went wrong.

    First, add the new member variables and our onCreate(...) method as below:

MemoEditActivity.java (1)

public class MemoEditActivity extends Activity {
    Button photoShareButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

       // Set photoShareButton
        photoShareButton = (Button)findViewById(R.id.button3);
        photoShareButton.getBackground().setColorFilter(Color.rgb(65, 183, 216), 
                                                            PorterDuff.Mode.SRC_IN);
        photoShareButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 
                new AsyncTask<String, Void, String>(){
                    @Override
                    protected String doInBackground(String... params) {        
                        return FlashAirRequest.getString(params[0]);    
                    }
                    @Override
                    protected void onPostExecute(String result) {
                        if(result.toUpperCase(Locale.getDefault()).equals("OK")) {
                            Intent photoShare = new Intent(getBaseContext(), 
                                                                PhotoShareActivity.class);
                            photoShare.putExtra("date", date);
                            photoShare.putExtra("dir", directoryName);
                            MemoEditActivity.this.startActivity(photoShare);
                        }else{
                            Toast.makeText(MemoEditActivity.this, "Enable failed.", 
                                                                Toast.LENGTH_LONG).show();
                        }                    
                    }
                }.execute("http://flashair/command.cgi?op=200&DIR=/" + directoryName 
                                                            + "&DATE=" + getDate16(date));
            }
        });        

    }

} // End SetScreenActivity class

We added the PhotoShare button hanndling MemoEditActivity.

  • Line 18:
    We set up PhotoShare.
  • Lines 22-30:
    We set the function to start the PhotoShare activity screen if the CGI command is successful.

The rest of MemoEditActivity.java can stay the same.

Creating the PhotoShare Activity

Initialization

We'll start by declaring our views and other class variables, as well as the screen formatting.
Next we'll need to override the onCreate(...) method so that we can initialize our Activity class.
The initialization method needs to setup the list as well as set the click listener for the Button.

PhotoShareActivity.java (1)

public class PhotoShareActivity extends Activity {

    ImageView imageView;
    Button backButton;
    TextView dateText;
    TextView currentDirText;
    String date;
    String rootDir = "DCIM";
    String directoryName;     

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photoshare);

        Bundle extrasData = getIntent().getExtras();
        date = extrasData.getString("date");
        directoryName = extrasData.getString("dir");

        // Set backButton
        backButton = (Button) findViewById(R.id.button1);
        backButton.getBackground().setColorFilter(Color.rgb(65, 183, 216), 
                                                    PorterDuff.Mode.SRC_IN);
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                disablePhotoShare();
            }
        });          
        currentDirText = (TextView)findViewById(R.id.textView1);
        currentDirText.setText(directoryName);          
        dateText = (TextView) findViewById(R.id.textView2);
        dateText.setText(date);          
     }
  • Lines 24-29:
    This sets it so that when the user hits the back button, we disable PhotoShare.

Disabling PhotoShare

We will be using command.cgi's op 201 to disable PhotoShare.

  • command.cgi with op=201
    • The command should look like this: http://flashair/command.cgi?op=201
    • It will return the following data:
      • OK If we've successfully disabled PhotoShare mode.
      • 400 Bad Request If something went wrong.

PhotoShareActivity.java (2)

 private void disablePhotoShare() {
     AlertDialog.Builder alertDialog=new AlertDialog
                                            .Builder(PhotoShareActivity.this);
     alertDialog.setTitle(R.string.app_name);
     alertDialog.setMessage("Do you disable PhotoShare?");
     // in case clicked OK
     alertDialog.setPositiveButton("OK",new DialogInterface.OnClickListener() {
         @Override
         public void onClick(DialogInterface dialog,int whichButton) {
            new AsyncTask<String, Void, String>(){
                @Override
                protected String doInBackground(String... params) {          
                    return FlashAirRequest.getString(params[0]);     
                }
                @Override
                protected void onPostExecute(String result) {
                    if(result.toUpperCase(Locale.getDefault()).equals("OK")) {
                        Toast.makeText(PhotoShareActivity.this, 
                               "Disable completed.", Toast.LENGTH_LONG).show();
                        PhotoShareActivity.this.finish(); // Go back
                    }else{
                        Toast.makeText(PhotoShareActivity.this, 
                               "Disable failed.", Toast.LENGTH_LONG).show();
                    }
                }
             }.execute("http://flashair/command.cgi?op=201");    
        }
    });
    // in case clicked Cancel
    alertDialog.setNegativeButton("Cancel", 
                                    new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog,int whichButton) {
        }
    });
    alertDialog.setCancelable(false);
    alertDialog.create();
    alertDialog.show();
 }
  • Line 13:
    We disable PhotoShare.
  • Lines 17-24:
    We return to the previous Activity of the CGI command was successful.

Handling the Back Key

We set the behaviour of someone hitting the back key to be identical to when the back button is pressed.

PhotoShareActivity.java (3)

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
     if(keyCode == KeyEvent.KEYCODE_BACK){
         disablePhotoShare();
         return false;
     }else{
         return super.onKeyDown(keyCode, event);
     }
 }

Result

Let's enable PhotoShare!
We will disable it first before testing.

This image shows the result
This image shows the result

Try to select 2013/03/03.

This image shows the result

Tap the PhotoShare button and set up PhotoShare.

This image shows the result
This image shows the result

Only the images in the specified folder and date are displayed.

This image shows the result

Sample Code

android_tutorial_08.zip (533KB)

All sample code on this page is licensed under BSD 2-Clause License